import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np

# 读取zixuan.jpg灰度图
img = cv.imread('1.jfif', 0)

# 给图形做极大极小值归一  min  max
img_max = img.max()  # 获取img最大值

img_min = img.min()  # 获取img最小值

img_to_one = (img - img_min) / (img_max - img_min)  # 得到img进行极小极大值归一的结果

img_OpenCv = cv.equalizeHist(img)  # 用OpenCV直接进行全局直方图均衡

h, _ = np.histogram(img.flatten(), 256, [0, 256])  # 获得img的直方图(分256个区间)

cdf = h.cumsum()  # 获得h对应的累积直方图

cdf = (cdf - cdf.min()) / (cdf.max() - cdf.min())  # 把累积直方图进行均值归一获得累积频率直方图

img_2 = cdf[img]  # 通过累积频率直方图对img进行全局直方图均衡

# 创建一个CLAHE算法对象,  8*8的小窗,  阈值为6
CLAHE = cv.createCLAHE(clipLimit=5.0, tileGridSize=(8, 8))

img_zi = CLAHE.apply(img)  # 使用CLAHE  进行自适应直方图均衡

fg, ax = plt.subplots(5, 2, figsize=(5, 10))
#  用完整的数据范围打印图像及其直方图
ax[0, 0].imshow(img, cmap='gray', vmin=0, vmax=255)
ax[0, 1].set_title('original low contrast image')
ax[0, 1].hist(img.ravel(), bins=256, range=[0, 255])

#  最小最大值归一
ax[1, 0].imshow(img_to_one, cmap='gray', vmin=0, vmax=1)
ax[1, 1].set_title('min-max  normalized  image')
ax[1, 1].hist(img_to_one.ravel(), bins=256, range=[0, 1])

#  全局直方图均衡
ax[2, 0].imshow(img_OpenCv, cmap='gray')
ax[2, 1].set_title('global  equalization: OpenCV')
ax[2, 1].hist(img_OpenCv.ravel(), bins=256)

ax[3, 0].imshow(img_2, cmap='gray')
ax[3, 1].set_title('global  equalization: Numpy')
ax[3, 1].hist(img_2.ravel(), bins=256)

#  自适应直方图均衡
ax[4, 0].imshow(img_zi, cmap='gray')
ax[4, 1].set_title('CLAHE: 8*8, 6')
ax[4, 1].hist(img_zi.ravel(), bins=256)

plt.tight_layout()
plt.savefig('out.png', bbox_inches='tight')
plt.show()
